module ActsAsSolr
  class QueryBuilder
    def initialize(options)
      @conditions = []
      @conditions += self.class.parse_conditions(options[:conditions])
      @order = options[:order]
    end

    def self.parse_conditions(conditions)
      result = []
      conditions = [conditions] unless conditions.is_a?(Array)
      conditions.each do |condition|
        if condition.is_a?(Hash)
          condition.each do |field,value|
            field = field.to_s.gsub("id", "pk_i") if field.to_s.starts_with?("id")
            if value.is_a?(Array)
              result << "(" + value.collect {|valu| "#{field}:#{quote_value(valu)}"}.join(" OR ") + ")"
            elsif value.is_a?(Range)
              result << "#{field}:[#{quote_value(value.first)} TO #{quote_value(value.last)}]"
            else
              if field.to_s.ends_with?("_gt")
                result << "#{field.to_s[0..-4]}:{#{quote_value(value)} TO *}"
              elsif field.to_s.ends_with?("_lt")
                result << "#{field.to_s[0..-4]}:{* TO #{quote_value(value)}}"
              elsif field.to_s.ends_with?("_le")
                result << "#{field.to_s[0..-4]}:[* TO #{quote_value(value)}]"
              elsif field.to_s.ends_with?("_ge")
                result << "#{field.to_s[0..-4]}:[#{quote_value(value)} TO *]"
              elsif field.to_s.ends_with?("_ne")
                result << "NOT #{field.to_s[0..-4]}:#{quote_value(value)}"
              else
                result << "#{field}:#{quote_value(value)}"
              end
            end
          end
        else
          result << condition
        end
      end
      result
    end

    def self.quote_value(valu)
      case valu
      when Date: valu.utc.iso8601
      when String, Symbol: "\"#{valu.to_s.gsub("\"", "\\\"")}\""
      else valu.to_s
      end
    end

    def to_s
      conditions_s + order_s
    end

    def conditions_s
      @conditions.select{|cond| !cond.blank?}.join(" AND ")
    end

    def order_s
      (@order ? ";#{@order}" : "")
    end

    def scope_options

    end

    def self.with_scope(options, &block)
      Thread.current["solr_scopes"] ||= []
      Thread.current["solr_scopes"] << options
      begin
        yield
      ensure
        Thread.current["solr_scopes"].pop
      end
    end
  end
end